package com.r2coding.music.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.r2coding.music.dao.*;
import com.r2coding.music.entity.*;
import com.r2coding.music.vo.req.QuerySongListReqVo;
import com.r2coding.music.vo.resp.SongListRespVo;
import com.r2coding.music.vo.resp.SongRespVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.r2coding.common.util.PageUtils;
import com.r2coding.common.util.Query;

import com.r2coding.music.service.SongListService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

/**
 * 歌单
 *
 * @author 98k灬
 * @email hk666zx@163.com
 * @date 2022-05-04 20:46:11
 */
@Service("songListService")
public class SongListServiceImpl extends ServiceImpl<SongListDao, SongListEntity> implements SongListService {

    @Autowired
    SongSongListDao songSongListDao;

    @Autowired
    SongListCategoryDao songListCategoryDao;

    @Autowired
    SongDao songDao;

    @Autowired
    SingerDao singerDao;

    @Autowired
    SongCategoryDao songCategoryDao;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<SongListEntity> page = this.page(
                new Query<SongListEntity>().getPage(params),
                new QueryWrapper<SongListEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public PageInfo<SongListRespVo> getList(QuerySongListReqVo vo) {
        PageHelper.startPage(vo.getCurrent(), vo.getSize());
        List<SongListRespVo> vos = this.baseMapper.getList(vo.getName(), vo.getCategoryId());
        return new PageInfo<SongListRespVo>(vos);
    }

    @Override
    public SongListRespVo getSongListById(Integer id) {
        return this.baseMapper.getSongListById(id);
    }

    @Transactional
    @Override
    public void delete(Integer id) {
        // 先删除该歌单下所有的歌曲信息
        songSongListDao.delete(new QueryWrapper<SongSongListEntity>().eq("song_list_id", id));
        // 删除该歌单
        this.baseMapper.deleteById(id);
    }

    @Override
    public SongListCategoryEntity getSongListCategoryById(Integer id) {
        // 根据歌单id查询歌单分类id
        SongListEntity songList = this.baseMapper.selectById(id);
        // 根据歌单分类id查询歌单分类信息
        return songListCategoryDao.selectById(songList.getCategoryId());
    }

    @Override
    public List<SongRespVo> getSongsById(Integer id) {
        List<SongEntity> songs = new ArrayList<>();
        // 根据歌单id查询名下所有的歌曲id
        List<SongSongListEntity> list = songSongListDao.selectList(new QueryWrapper<SongSongListEntity>().eq("song_list_id", id));
        if (!CollectionUtils.isEmpty(list)) {
            List<Integer> collect = list.stream().map(SongSongListEntity::getSongId).collect(Collectors.toList());
            songs = songDao.selectBatchIds(collect);
        }

        List<SongRespVo> collect = new ArrayList<>();
        if (!CollectionUtils.isEmpty(songs)) {
            collect = songs.stream().map(item -> {
                SongRespVo respVo = new SongRespVo();
                BeanUtils.copyProperties(item, respVo);
                return respVo;
            }).collect(Collectors.toList());
        }

        for (SongRespVo respVo : collect) {
            for (SongEntity song : songs) {
                // 根据歌手id查询歌手信息
                SingerEntity singer = singerDao.selectById(song.getSingerId());
                respVo.setSingerName(singer.getSingerName());
                // 根据歌曲分类id查询歌曲分类信息
                SongCategoryEntity category = songCategoryDao.selectById(song.getSongCategoryId());
                respVo.setSongCategoryName(category.getCategoryName());
            }
        }
        return collect;
    }
}